/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tolls;

import avenue.Session;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.swing.JOptionPane;
import model.Collection;
import model.ProgramRate;
import model.Vehicle;

/**
 *
 * @author tasos
 */
public class PassForm extends javax.swing.JInternalFrame {

    /**
     * Creates new form PassForm
     */
    public PassForm() {
        em = Session.emf.createEntityManager();
        em.getTransaction().begin();
        initComponents();
        this.payButton.setEnabled(false);
        this.passButton.setEnabled(false);
    }
    
    private void checkBalance() {
        
        double balance = vehicle1.getCardId().getBalance();
        double rate = programRate1.getRate().doubleValue();
        
        messageLabel.setText("");
        cardBalanceTF.setText(vehicle1.getCardId().getBalance().toString());
        
        if (balance >= rate) { 
            canPass = true;
        } else {
            messageLabel.setText(messageLabel.getText() + " Το υπόλοιπο της κάρτας δεν επαρκεί για την διέλευση.");
            canPass = false;
        }
        
        if (balance < 5.00) { 
            messageLabel.setText(messageLabel.getText() + " Το υπόλοιπο της κάρτας είναι κάτω από 5 ευρώ.");
        }
                
        if (canPass) {
            this.passButton.setEnabled(true);
        } else {
            this.passButton.setEnabled(false);
        }
    }
    
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        vehicle1 = new model.Vehicle();
        programRate1 = new model.ProgramRate();
        cancelButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        regNumberTF = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        cardIdTF = new javax.swing.JTextField();
        CheckVehicle = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        cardBalanceTF = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        numOfPassesTF = new javax.swing.JTextField();
        messageLabel = new javax.swing.JLabel();
        passButton = new javax.swing.JButton();
        payButton = new javax.swing.JButton();
        freePassLabel = new javax.swing.JLabel();

        setTitle("Διέλευση Οχήματος");

        cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/cancel.gif"))); // NOI18N
        cancelButton.setLabel("Άκυρο");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        jLabel1.setText("Αρ. Κυκλοφορίας: ");

        jLabel2.setText("Αρ. Κάρτας: ");

        CheckVehicle.setText("Έλεγχος ταυτότητας του οχήματος");
        CheckVehicle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CheckVehicleActionPerformed(evt);
            }
        });

        jLabel3.setText("Υπόλοιπο Κάρτας: ");

        cardBalanceTF.setEditable(false);

        jLabel5.setText("Πλήθος διελεύσεων τρέχοντα μήνα:");

        numOfPassesTF.setEditable(false);

        messageLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N

        passButton.setText("Διέλευση");
        passButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                passButtonActionPerformed(evt);
            }
        });

        payButton.setLabel("Πληρωμή");
        payButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                payButtonActionPerformed(evt);
            }
        });

        freePassLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(messageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(layout.createSequentialGroup()
                                    .addComponent(jLabel1)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(regNumberTF, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(18, 18, 18)
                                    .addComponent(jLabel2)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(cardIdTF, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(18, 18, 18)
                                    .addComponent(CheckVehicle))
                                .addGroup(layout.createSequentialGroup()
                                    .addComponent(jLabel3)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(cardBalanceTF, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(18, 18, 18)
                                    .addComponent(jLabel5)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                    .addComponent(numOfPassesTF, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGap(18, 18, 18)
                                    .addComponent(payButton)
                                    .addGap(18, 18, 18)
                                    .addComponent(passButton)))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(224, 224, 224)
                                .addComponent(cancelButton)))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(freePassLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(regNumberTF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cardIdTF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(CheckVehicle))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(messageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(4, 4, 4)
                .addComponent(freePassLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(cardBalanceTF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5)
                    .addComponent(numOfPassesTF, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(payButton)
                    .addComponent(passButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 43, Short.MAX_VALUE)
                .addComponent(cancelButton)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        try {
            em.getTransaction().rollback();
            this.dispose();
        }
        catch (Exception ex) {
            JOptionPane.showMessageDialog(this, ex.getMessage());
        }
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void CheckVehicleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CheckVehicleActionPerformed
        freePassLabel.setText("");
        this.payButton.setEnabled(false);
        this.payButton.setEnabled(false);
        // Έλεγχος των δεδομένων εισόδου
        String regNumber = regNumberTF.getText().trim();
                
        if (regNumber.equals("")) {
            JOptionPane.showMessageDialog(this,"Ο αριθμός κυκλοφορίας είναι κενός.");  
            return;
        }         
        
        Integer cardId;
        try { 
            cardId = Integer.parseInt(cardIdTF.getText());
        } catch(NumberFormatException ex) { 
            JOptionPane.showMessageDialog(this,"Μη έγκυρος αριθμός κάρτας.");
            return;
        }
        
        // Αναζήτησε το όχημα με τον εν λόγω αριθμό πινακίδας και τον εν
        // λόγω αριθμό κάρτας
        Query vehicleQuery = em.createQuery("select v from Vehicle v where "
                + "v.regNumber = :regnum and v.cardId.barcode = :cardnum");
        
        vehicleQuery.setParameter("regnum", regNumber);
        vehicleQuery.setParameter("cardnum", cardId);
        
        try { 
            // Εκτέλεση της επερώτησης
            vehicle1 = (Vehicle) vehicleQuery.getSingleResult();
        } catch(NoResultException ex) { 
            // Το όχημα δεν βρέθηκε
            JOptionPane.showMessageDialog(this,"Ο συνδυασμός οχήματος/κάρτας δεν βρέθηκε.");
            return;
        } catch(Exception ex) { 
            JOptionPane.showMessageDialog(this,ex.getMessage());
            return;
        }
        
        // Αναζήτησε την χρεώση που αντιστοιχεί στον τρέχων σταθμό, για το
        // τρέχον είδος οχήματος και για το εν λόγω πρόγραμμα
        Query programRateQuery = em.createQuery("select pr from ProgramRate pr where "
                + "pr.stationId = :stationId and pr.categoryId = :categoryId and "
                + "pr.programId = :programId");
        programRateQuery.setParameter("stationId", Session.getUser().getStationId());
        programRateQuery.setParameter("categoryId", vehicle1.getCategoryId());
        programRateQuery.setParameter("programId", vehicle1.getCardId().getProgramId());
        
        try { 
            // Εκτέλεση της επερώτησης
            programRate1 = (ProgramRate) programRateQuery.getSingleResult();
            freePassLabel.setText("Η διέλευση χρεώνεται " + programRate1.getRate().toString());
        } catch(Exception ex) { 
            // Πρόβλημα κατά την ανάκτηση της χρέωσης
            JOptionPane.showMessageDialog(this,ex.getMessage());
            return;
        }
        
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        Date start = cal.getTime();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date end = cal.getTime();
        Query numOfPassesQuery = em.createQuery("select c from Collection c where "
                + "c.cardId = :cardId AND c.passTimestamp between :start and :end");
        numOfPassesQuery.setParameter("cardId", vehicle1.getCardId());
        numOfPassesQuery.setParameter("start", start);
        numOfPassesQuery.setParameter("end", end);
        
        List<Collection> collections;
        try { 
             collections = numOfPassesQuery.getResultList();
        } catch(Exception ex) { 
            JOptionPane.showMessageDialog(this,ex.getMessage());
            return;
        }
        
        Integer numOfPasses = collections.size();
        
        numOfPassesTF.setText(numOfPasses.toString());
        
        if (vehicle1.getCardId().getProgramId().getPassLimit() != null &&
                vehicle1.getCardId().getProgramId().getFreePass() != null) {
            int passlimit = vehicle1.getCardId().getProgramId().getPassLimit();
            int freepass = vehicle1.getCardId().getProgramId().getFreePass();
            if (passlimit < numOfPasses && numOfPasses < passlimit + freepass) { 
                freePassLabel.setText("Η διέλευση δεν χρεώνεται.");
                isFreePass = true;
            } else {
                isFreePass = false;
            }
        }
        
        this.payButton.setEnabled(true);
        checkBalance();
    }//GEN-LAST:event_CheckVehicleActionPerformed
    
    private void passButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_passButtonActionPerformed

        double tollCollected;
        if (isFreePass) {
            tollCollected = 0;
        } else {
            tollCollected = programRate1.getRate().doubleValue();
            double oldBalance = vehicle1.getCardId().getBalance();
            vehicle1.getCardId().setBalance(oldBalance - tollCollected);
        }

        Collection col = new Collection();
        col.setCardId(vehicle1.getCardId());
        col.setTollCollected(new BigDecimal(tollCollected));
        col.setPassTimestamp(new Date());
        col.setStationId(Session.getUser().getStationId());
        em.persist(col);

        em.getTransaction().commit();
        em.getTransaction().begin();

        dispose();
    }//GEN-LAST:event_passButtonActionPerformed

    private void payButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_payButtonActionPerformed
        if (!Session.CheckPermission(Session.PAYMENTS_MODULE)) {
            return;
        }
        PayForm frm = new PayForm(null,true,vehicle1);
        frm.setVisible(true);
        em.refresh(vehicle1);
        checkBalance();
    }//GEN-LAST:event_payButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton CheckVehicle;
    private javax.swing.JButton cancelButton;
    private javax.swing.JTextField cardBalanceTF;
    private javax.swing.JTextField cardIdTF;
    private javax.swing.JLabel freePassLabel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel messageLabel;
    private javax.swing.JTextField numOfPassesTF;
    private javax.swing.JButton passButton;
    private javax.swing.JButton payButton;
    private model.ProgramRate programRate1;
    private javax.swing.JTextField regNumberTF;
    private model.Vehicle vehicle1;
    // End of variables declaration//GEN-END:variables
    private EntityManager em;
    private boolean canPass = false;
    private boolean isFreePass = false;
}
